package nafos.server.structure;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * @Description 满环数组，填充元素形成满环即触发回调
 * @Author xinyu.huang
 * @Time 2020/2/12 22:46
 */
public class FullRingList<T> {
    private Logger logger = LoggerFactory.getLogger(FullRingList.class);

    private int listSize;

    private int index = 0;

    private final ArrayList<T> tList;

    private final ArrayList<T> singleBean = new ArrayList(1);

    private volatile boolean readyShutdown = false;

    private final LinkedBlockingQueue<T> queue = new LinkedBlockingQueue();

    private final FullRingListFullEvent fullRingListFullEvent;

    public FullRingList(int fullSize, FullRingListFullEvent event) {
        listSize = fullSize;
        tList = new ArrayList(listSize);
        for (int i = 0; i < listSize; i++) {
            tList.add(null);
        }
        fullRingListFullEvent = event;
        new Thread(() -> {
            for (; ; ) {
                try {
                    T t = queue.take();
                    addToRing(t);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    logger.error(e.toString());
                }
            }
        }).start();
    }

    /***
     *@Description 环组填充
     *@Author xinyu.huang
     *@Time 2020/2/12 23:26
     */
    private void addToRing(T t) {
        if (readyShutdown) {
            singleBean.set(0, t);
            fullRingListFullEvent.event(singleBean);
        }
        if (index >= listSize) {
            fullRingListFullEvent.event(tList);
            index = 0;
        }
        tList.set(index, t);
        index++;
    }

    /***
     *@Description 向环状数组中添加元素，满环时返回元素
     *@Author xinyu.huang
     *@Time 2020/2/12 17:02
     */
    public void add(T t) {
        try {
            queue.put(t);
        } catch (InterruptedException e) {
            e.printStackTrace();
            logger.error(e.toString());
        }
    }

    /***
     *@Description 关机状态
     *@Author xinyu.huang
     *@Time 2020/2/12 22:12
     */
    public void shutdown() {
        if (readyShutdown) throw new RuntimeException("CollectionHandle been shutdown");
        readyShutdown = true;
        if (index == 0) return;
        fullRingListFullEvent.event((ArrayList) tList.subList(0, index));
    }

    public interface FullRingListFullEvent<T> {
        void event(ArrayList<T> t);
    }

}


